package com.siwei.mes.sync.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.concurrent.*;

/**
 * 项目启动初始化线程
 *
 * @Description: 项目启动初始化线程
 * @Version: 1.0
 * @author: chenmaolin
 * @date: 2024/2/3 11:48
 */
@Service
@Component
public class SyncProcessorInitializing implements InitializingBean, DisposableBean {
    @Resource
    private SyncProcessorService syncProcessorService;

    private static final Logger log = LoggerFactory.getLogger("job");

    /**
     * 对应操作数据的队列
     */
    private BlockingQueue<Object> queue = null;
    /**
     * 只有一个线程的线程池
     */
    private ExecutorService workers;
    /**
     * 是否运行
     */
    private boolean runnable = true;
    /**
     * 休眠时间
     */
    private long sleepTime = 3000;

    public void process() {
        while (runnable) {
            try {
                if (queue.isEmpty()) {
                    this.sleep();
                } else {
                    Object entityObject = queue.take();
                    syncProcessorService.processRequest(entityObject);
                }
            } catch (Exception e) {
                log.error("处理队列数据时发生异常", e);
                this.sleep();
            }
        }
        log.info("同步任务处理器退出");
    }

    /**
     * 线程休眠
     */
    public void sleep() {
        try {
            TimeUnit.MILLISECONDS.sleep(sleepTime);
        } catch (InterruptedException e) {
            log.warn("Thread interrupt exception", e);
        }
    }

    public void sleep(long time) {
        try {
            TimeUnit.MILLISECONDS.sleep(time);
        } catch (InterruptedException e) {
            log.warn("Thread interrupt exception", e);
        }
    }

    @Override
    public void destroy() throws Exception {
        this.runnable = false;
        if (this.workers != null) {
            workers.shutdown();
        }
    }

    @Override
    public void afterPropertiesSet() {
        this.workers = Executors.newSingleThreadExecutor();
        this.queue = new LinkedBlockingQueue<>();
        log.info("初始化 SyncProcessor 配置成功，队列是否为空: {}", this.queue == null);
        this.workers.execute(this::process);
        log.info("初始化 SyncProcessor 配置成功");
    }

    /**
     * 添加数据到队列
     *
     * @param request
     * @return true-添加成功 false-添加失败
     */
    public boolean submitRequest(Object request) {
        if (this.queue == null) {
            log.error("队列未初始化，重新初始化队列");
            this.queue = new LinkedBlockingQueue<>();
        }
        int maxRetries = 3; // 最大重试次数
        int retries = 0;

        while (retries <= maxRetries) {
            boolean result = this.queue.offer(request);
            if (result) {
                log.info("添加数据到队列成功，队列当前大小: {}", this.queue.size());
                return true;
            } else {
                if (retries < maxRetries) {
                    log.info("添加数据到队列失败，等待 5 秒后重试，队列当前大小: {}", this.queue.size());
                    try {
                        // 等待 5 秒后重试
                        TimeUnit.SECONDS.sleep(5);
                    } catch (InterruptedException e) {
                        log.error("等待过程中线程被中断", e);
                        return false;
                    }
                } else {
                    log.error("添加数据到队列失败，达到最大重试次数，队列当前大小: {}", this.queue.size());
                }
                retries++;
            }
        }
        return false;
    }


    /**
     * 获取队列长度
     *
     * @return
     */
    public Integer size() {
        return queue.size();
    }


    public static void main(String[] args) {
        ExecutorService executor = Executors.newSingleThreadExecutor();

        Runnable task1 = () -> {
            System.out.println("Task 1 is running.");
            try {
                Thread.sleep(2000); // 模拟任务执行时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Task 1 finished.");
        };

        Runnable task2 = () -> {
            System.out.println("Task 2 is running.");
            try {
                Thread.sleep(2000); // 模拟任务执行时间
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Task 2 finished.");
        };

        executor.execute(task1);
        executor.execute(task2);

        // 关闭线程池，以优雅的方式
        executor.shutdown();
    }

}
